<?php
namespace app\api\model\food;

use app\common\model\food\Order as OrderModel;
use app\api\model\Setting as SettingModel;
use hema\Helper;
use hema\wechat\Pay as WxPay;
use think\facade\Cache;
use think\facade\Db;
use hema\delivery\Driver as Delivery;

/**
 * 订单模型
 */
class Order extends OrderModel
{
    /**
     * 隐藏字段
     */
    protected $hidden = [
    ];
	
    /**
     * 订单确认-购物车结算
     */
    public function getCart($user,$order_mode = 0, $shop_id = 0, $coupon_user_id = 0,$table_id='')
    {
        $model = new Cart($user['user_id'],$shop_id,self::$applet_id,$table_id);
        return $model->getList($user,$order_mode,$coupon_user_id);
    }

    /**
     * 新增订单
     */
    public function add(array $order,$coupon_user_id)
    {
		//如果是外卖
		if($order['order_mode']==20){
			if (empty($order['address'])) {
				$this->error = '请先选择收货地址';
				return false;
			}
			//计算是否在配送范围
			if(empty($order['address']['location'])){
				$this->error = '请重新完善收货地址';
				return false;
			}
			$shop = Shop::detail($order['shop_id'],$order['address']['location']);
			$delivery = Setting::getItem('delivery');//获取派送设置
			if($delivery['delivery_range'] < $shop['distance']){
				$this->error = '您已超出派送范围';
				return false;
			}
		}
		$order['order_no'] = order_no();
		$order['total_price'] = $order['order_total_price'];
		$order['pay_price'] = Helper::number2($order['order_pay_price']);	//实付金额
		// 开启事务
        Db::startTrans();
        try {
			// 记录订单信息
			$this->save($order);
			// 订单商品列表
			$goodsList = [];
			foreach ($order['goods_list'] as $goods) {
				/* @var Goods $goods */
				$goodsList[] = [
					'user_id' => $order['user_id'],
					'applet_id' => $order['applet_id'],
					'goods_id' => $goods['goods_id'],
					'goods_name' => $goods['goods_name'],
					'image_id' => isset($goods['goods_sku']['image']['url'])?$goods['goods_sku']['image_id']:$goods['image'][0]['image_id'],
					'spec_type' => $goods['spec_type'],
					'spec_sku_id' => $goods['goods_sku']['spec_sku_id'],
					'goods_spec_id' => $goods['goods_sku']['goods_spec_id'],
					'goods_attr' => $goods['goods_sku']['goods_attr'],
					'content' => $goods['content'],
					'goods_price' => $goods['goods_sku']['goods_price'],
					'line_price' => $goods['goods_sku']['line_price'],
					'total_num' => $goods['total_num'],
					'total_price' => $goods['total_price'],
				];
			}
            //核销优惠券
            if($coupon_user_id){
                $coupon = CouponUser::get($coupon_user_id,['coupon']);
                //满赠券
                if($coupon['type']['value'] == 30){
                    //3满赠 = { condition=满足数值条件 {10金额 20数量} num = 数值 type = 赠品类型 {10优惠券 20商品} gift = 礼物{ id=编号 name=名称 image=图片 }
                    if($coupon['coupon']['values']['type'] == 10){
                        //优惠券
                        $quan[0] = Coupon::get($coupon['coupon']['values']['gift']['id']);
                        $model = new CouponUser;
                        $model->add($quan,$order['user_id']);
                    }
                    if($coupon['coupon']['values']['type'] == 20){
                        //商品
                        $goods = Goods::detail($coupon['coupon']['values']['gift']['id']);
                        $goodsList[] = [
                            'user_id' => $order['user_id'],
                            'applet_id' => $order['applet_id'],
                            'goods_id' => $goods['goods_id'],
                            'goods_name' => $goods['goods_name'],
                            'spec_type' => $goods['spec_type'],
                            'total_num' => 1,
                            'total_price' => 0.00,
                            'content' => $goods['content'],
                            'image_id' => $goods['image'][0]['image_id'],
                            'spec_sku_id' => $goods['spec'][0]['spec_sku_id'],
                            'goods_spec_id' => $goods['spec'][0]['goods_spec_id'],
                            'goods_attr' => '赠品',
                            'goods_price' => $goods['spec'][0]['goods_price'],
                            'line_price' => $goods['spec'][0]['line_price'],
                        ];
                    }
                }
                $coupon->remove();
            }
			// 保存订单商品信息
			$this->goods()->saveAll($goodsList);
			//如果是外卖,记录收货地址
			if($order['order_mode']==20){
				$this->address()->save([
					'user_id' => $order['user_id'],
					'applet_id' => $order['applet_id'],
					'name' => $order['address']['name'],
					'phone' => $order['address']['phone'],
					'location' => $order['address']['location'],
					'province' => $order['address']['province'],
					'city' => $order['address']['city'],
					'district' => $order['address']['district'],
					'detail' => $order['address']['detail'],
				]);
			}
			Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
        }
        return false;
    }

    /**
     * 订单详情
     */
    public static function getUserOrderDetail($order_id, $user_id)
    {
        if (!$order = self::get(['order_id' => $order_id,'user_id' => $user_id], ['goods' => ['spec', 'goods','image'], 'address', 'shop', 'table','delivery'])) {
            $this->error = '订单不存在';
        	return false;
        }
        return $order;
    }

    /**
     * 取消订单
     */
    public function userCancel()
    {
        if ($this->pay_status['value'] == 20 OR $this->shop_status['value'] > 10 ) {
            $this->error = '当前订单状态不可取消';
            return false;
        }
        //堂食扫码释放餐桌
        if($this->table_id > 0){
            Table::where(['table_id' => $this->table_id])->update(['status' => 10]);
        }
        return $this->save(['order_status' => 20]);
    }

    /**
     * 退款订单
     */
    public function userRefund(array $data)
	{
		$order = Cache::get('refund_' . $this->order_id . '_' . $this->user_id . '_' . $this->shop_id);
        $order['refund_desc'] = $data['desc'];
		$goods = [];
		if($data['mode']==1){
			//全单退
			$order['refund_price'] = $order['pay_price'];
			for($n=0;$n<sizeof($order['goods']);$n++){
				$goods[$n]['order_goods_id'] = $order['goods'][$n]['order_goods_id'];
                $goods[$n]['refund_num'] = $order['goods'][$n]['refund_num'];
                $goods[$n]['refund_price'] = $order['goods'][$n]['refund_price'];
                $order['goods'][$n]['refund_num'] = $order['goods'][$n]['total_num'];
                $order['goods'][$n]['refund_price'] = $order['goods'][$n]['total_price'];
			}
		}else{
			//部分退
			for($n=0;$n<sizeof($order['goods']);$n++){
				$goods[$n]['order_goods_id'] = $order['goods'][$n]['order_goods_id'];
				$goods[$n]['refund_num'] = $order['goods'][$n]['refund_num'];
				$goods[$n]['refund_price'] = $order['goods'][$n]['refund_price'];
			}
		}
		// 开启事务
        Db::startTrans();
        try {
			$this->save([
				'refund_price'  => $order['refund_price'],//退款金额
				'refund_desc'  => $order['refund_desc'],//退款理由
				'order_status' => 40,//退款状态
				'refund_time' => time(),//退款时间
			]);
            foreach ($goods as $value) {
                OrderGoods::where('order_goods_id',$value['order_goods_id'])->update($value);
            }
			Db::commit();
            sand_refund_msg($order);//给管理和店长发送退款申请模板消息
            Device::print($order,1);//打印退款商品订单
            return true;
        } catch (\Exception $e) {
            Db::rollback();
        }
        return false;
	}

    /**
     * 用户支付
     */
    public function userPay($pay_mode)
    {
        // 发起微信支付
        if($pay_mode==0){
            $divide = false;//分账状态
            //验证外卖订单是否要分账配送费
            if($this->order_mode['value'] == 20){
                $dv = new Delivery();
                if($company = $dv->company()){
                    foreach ($company as $item){
                        if($item['name'] != 'sf' AND $item['config']['pay_mode'] == 1){
                            $divide = true;
                            break;
                        }
                    }
                }
            }
            //获取小程序配置的支付参数
            $wxpay = new WxPay(SettingModel::getItem('wxpay'));
            return [
                'payment' => $wxpay->unifiedorder('JSAPI',$this->order_no,$this->pay_price,'api/food.notify/order',$this->user['open_id'],'订单支付',$divide),
                'order_id' => $this->order_id
            ];
        }
        //发起余额支付
        if($pay_mode==1){
            $user = User::get($this->user_id);
            if($user['money'] < $this->pay_price){
                $this->error = '余额不足！';
                return false;
            }
            $user->money = ['dec',$this->pay_price];//扣除余额
            $user->pay = ['inc', $this->pay_price];//增加消费金额
            $user->score = ['inc', $this->pay_price];//增加消费积分
            $user->save();
            $this->pay_status = 20;// 支付状态
            //新增余额消费记录
            $model = new Record;
            $model->add($this,40);
        }
        //发起后付款
        if($pay_mode==2){
            $this->pay_status = 30;// 支付状态
        }
        $this->pay_time = time();//付款时间
        $this->save(); 
        // 更新商品库存、销量
        $goods = new Goods;
        $goods->updateStockSales($this->goods);
        //商家是否自动接单
        if($this->shop['is_order']['value'] == 1){
            $this->setShopStatus();
            //外卖自动推送订单
            if($this->order_mode['value']==20 AND $this->shop['is_delivery']['value'] == 1){
                if(!$this->setDelivery($this->shop['delivery'])){
                   return false;
                }
            }
        }
        Device::push($this->shop_id,'new');//新订单提醒
        Device::print($this);//打印订单
        sand_new_order_msg($this);//发送模板消息 - 使用公众号
        return [
            'order_id' => $this->order_id
        ];
    }
    
    /**
     * 待支付订单详情 - 支付回调
     */
    public function payDetail($order_no)
    {
        return self::with(['goods','shop','table','address'])->where(['order_no' => $order_no, 'pay_status' => 10])->find();
    }

    /**
     * 更新付款状态 - 支付回调
     */
    public function updatePayStatus($transaction_id)
    {
		
		if($this['pay_status']['value']==20){
			//避免重复回调
			return true;
		}
		// 更新商品库存、销量
		$GoodsModel = new Goods;
		$GoodsModel->updateStockSales($this->goods);
		//天加交易记录
		$record = new Record;
		$record->save([
			'order_no' => $this['order_no'],
            'money' => $this['pay_price'],
            'user_id' => $this['user_id'],
            'shop_id' => $this['shop_id'],
            'applet_id' => $this['applet_id'],
            'action' => 40,//消费
            'type' => 30,//微信
            'remark' => '订单支付'
		]);
		//更新用户信息
		$user = User::get($this->user_id);
		$user->pay = ['inc', $this->pay_price];//增加消费金额
		$user->score = ['inc', $this->pay_price];//增加积分
		$user->save();
		// 更新订单状态
		$this->save([
			'pay_status' => 20,
			'pay_time' => time(),
			'transaction_id' => $transaction_id,
		]);
		//发送新订单提醒，管理员,店长
		sand_new_order_msg($this);
		Device::print($this);//打印订单
		Device::push($this->shop_id,'pay',$this->pay_price);//收款提醒
		//商家是否自动接单
		if($this['shop']['is_order']['value'] == 1){
			$this->setShopStatus();
			//外卖自动推送订单
			if($this['order_mode']['value']==20 AND $this['shop']['is_delivery']['value'] == 1){
				$this->setDelivery($this['shop']['delivery']);
			}
		}
		return true;
    }
    
    /**
     * 待退款订单详情 - 微信退款回调
     */
    public function refundDetail($order_no)
    {
		return self::get(['order_no' => $order_no, 'order_status' => 40, 'refund_status' => 10], ['goods']);
    }
	
	/**
     * 更新退款款状态 - 微信退款回调
     */
    public function updateRefundStatus($refund_id)
    {
		if(!empty($this->refund_id)){
			//避免重复回调
			return true;
		}
		//更新商品库存、销量
		//$GoodsModel = new Goods;
		//$GoodsModel->updateStockSales($this['goods']);
		//更新用户信息
		$user = User::get($this->user_id);
		$user->pay = ['dec', $this->refund_price];//扣减消费金额
		$user->score = ['dec', $this->refund_price];//扣减积分
		$user->save();
		//添加交易记录
		$record = new Record;
		$record->save([
			'order_no' => $this['order_no'],
            'money' => $this['refund_price'],
            'user_id' => $this['user_id'],
            'shop_id' => $this['shop_id'],
            'applet_id' => $this['applet_id'],
            'action' => 60,//退款
            'type' => 30,//微信
            'remark' => '订单退款'
		]);
		// 更新订单状态
		$this->save([
			'refund_status' => 20,
			'refund_time' => time(),
			'refund_id' => $refund_id,
		]);
		//发送退款申请状态提醒订阅消息
		food_post_tpl('refund',$this->order_id);
		return true;
    }
    
    /**
     * 更新第三方配送状态
     */
    public function updateDeliveryStatus($data,$mode)
    {
    	$dev['delivery_time'] = time();
		if($mode == 'dada'){
			//待接单＝1,待取货＝2,配送中＝3,已完成＝4,已取消＝5, 指派单=8,妥投异常之物品返回中=9, 妥投异常之物品返回完成=10, 骑士到店=100,创建达达运单失败=1000
			switch ((string)$data['order_status']) {
	            case '2': //已接单 - 骑手正赶往商家
					$dev = [
						'delivery_status' => 20,
						'linkman' => $data['dm_name'],
						'phone' => $data['dm_mobile']
					];
	                break;
	            case '100': //已到店 - 骑手已到店
					$dev = [
						'delivery_status' => 30
					];
	                break;
	            case '3': //已取件 - 骑手开始配送
					$dev = [
						'delivery_status' => 40
					];
	                break;
	            case '4';//到达目的地 - 骑手已送达
					$dev = [
						'delivery_status' => 50,
						'status' => 30
					];
					$this->save([
						'delivery_status' => 30,
						'delivery_time' => time()
					]);
	                break;
	            case '5': //订单被取消
					$dev = [
						'delivery_status' => 10,
						'shop_status' => 20
					];
					$this->save($dev);
					OrderDelivery::where('order_id',$this->order_id)->delete();
					return true;
	                break;
	            default:
	            	return true;
	        }
		}
		if($mode == 'sf'){
			switch ((string)$data['order_status']) {
	            case '10': //已接单 - 骑手正赶往商家
					$dev = [
						'delivery_status' => 20,
						'linkman' => $data['operator_name'],
						'phone' => $data['operator_phone']
					];
	                break;
	            case '12': //到店 - 骑手已到店
					$dev = [
						'delivery_status' => 30
					];
	                break;
	            case '15': //已取件 - 骑手开始配送
					$dev = [
						'delivery_status' => 40
					];
	                break;
	            case '17';//到达目的地 - 骑手已送达
					$dev = [
						'delivery_status' => 50,
						'status' => 30
					];
					$this->save([
						'delivery_status' => 30,
						'delivery_time' => time()
					]);
	                break;
	            case '22': //订单被取消 - 配送员撤单
					$dev = [
						'delivery_status' => 10,
						'shop_status' => 20
					];
					$this->save($dev);
					OrderDelivery::where('order_id',$this->order_id)->delete();
					return true;
	                break;
	            case '2': //订单被取消 - 顺丰原因
					$dev = [
						'delivery_status' => 10,
						'shop_status' => 20
					];
					$this->save($dev);
					OrderDelivery::where('order_id',$this->order_id)->delete();
					return true;
	                break;
	            default:
	            	return true;
	        }
		}
		if($mode == 'uu'){
			//当前状态1下单成功 3跑男抢单 4已到达 5已取件 6到达目的地 10收件人已收货 -1订单取消
			switch ((string)$data['state']) {
	            case '3': //已接单 - 骑手正赶往商家
					$dev = [
						'delivery_status' => 20,
						'linkman' => $data['driver_name'],
						'phone' => $data['driver_mobile']
					];
	                break;
	            case '4': //已到店 - 骑手已到店
					$dev = [
						'delivery_status' => 30
					];
	                break;
	            case '5': //已取件 - 骑手开始配送
					$dev = [
						'delivery_status' => 40
					];
	                break;
	            case '6';//到达目的地 - 骑手已送达
					$dev = [
						'delivery_status' => 50,
						'status' => 30
					];
					$this->save([
						'delivery_status' => 30,
						'delivery_time' => time()
					]);
	                break;
	            case '-1': //订单被取消
					$dev = [
						'delivery_status' => 10,
						'shop_status' => 20
					];
					$this->save($dev);
					OrderDelivery::where('order_id',$this->order_id)->delete();
					return true;
	                break;
	            default:
	            	return true;
	        }
		}
		if($mode == 'make'){
			//loading = 待付款', cancel='订单已取消', payed='待接单',wait_to_shop='待到店', accepted='待取件', geted='待收件',gotoed= '待评价', completed='订单已完成');
			switch ($data['status']) {
	            case 'accepted': //已接单 - 骑手正赶往商家
					$dev = [
						'delivery_status' => 20,
						'linkman' => $data['rider_name'],
						'phone' => $data['rider_mobile']
					];
	                break;
	            case 'wait_to_shop': //已到店 - 骑手已到店
					$dev = [
						'delivery_status' => 30
					];
	                break;
	            case 'geted': //已取件 - 骑手开始配送
					$dev = [
						'delivery_status' => 40
					];
	                break;
	            case 'gotoed';//到达目的地 - 骑手已送达
					$dev = [
						'delivery_status' => 50,
						'status' => 30
					];
					$this->save([
						'delivery_status' => 30,
						'delivery_time' => time()
					]);
	                break;
	            case 'payed': //订单被取消
					$dev = [
						'delivery_status' => 10,
						'shop_status' => 20
					];
					$this->save($dev);
					OrderDelivery::where('order_id',$this->order_id)->delete();
					return true;
	                break;
	            default:
	            	return true;
	        }
		}
		OrderDelivery::where('order_id',$this->order_id)->update($dev);
		return true;
	}

    /**
     * 设置错误信息
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    /**
     * 是否存在错误
     */
    public function hasError()
    {
        return !empty($this->error);
    }
}
